package org.tinygame.herostory.rank;

import com.alibaba.fastjson.JSONObject;
import netscape.javascript.JSObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinygame.herostory.async.AsyncOperationProcessor;
import org.tinygame.herostory.async.IAsyncOperation;
import org.tinygame.herostory.util.RedisUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * @author anan
 * @create 2022-05-08 0:09
 */
public class RankService {

    static private final Logger LOGGER = LoggerFactory.getLogger(RankService.class);

    private RankService(){}

    static private final RankService _instance = new RankService();

    static public RankService getInstance(){
        return _instance;
    }

    public void getRank(Function<List<RankItem>, Void> callback){
        if(null == callback) return;

        AsyncOperationProcessor.getInstance().process(new AsyncGetRank(){

            @Override
            public void doFinish() {
                callback.apply(this.getRankItemList());
            }
        });
    }

    public void refreshRank(int winnerId, int loserId){
        if(winnerId <= 0 || loserId <= 0){
            return;
        }
        try (Jedis redis = RedisUtil.getJedis()){
            redis.hincrBy("User_" + winnerId, "Win", 1);
            redis.hincrBy("User_" + loserId, "Lose", 1);

            String winStr = redis.hget("User_" + winnerId, "Win");
            int winNum = Integer.parseInt(winStr);

            redis.zadd("Rank", winNum, String.valueOf(winnerId));
        }catch (Exception e){
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * 异步方式获取排行榜
     */
    static private class AsyncGetRank implements IAsyncOperation{

        private List<RankItem> _rankItemList;

        List<RankItem> getRankItemList(){
            return _rankItemList;
        }


        @Override
        public void doAsync() {
            try (Jedis redis = RedisUtil.getJedis()){
                //获取集合字符串
                Set<Tuple> valSet = redis.zrevrangeWithScores("Rank", 0, 9);
                List<RankItem> rankItemList = new ArrayList<>();
                int i = 0;

                for(Tuple t : valSet){
                    if(null == t){
                        continue;
                    }
                    int userId = Integer.parseInt(t.getElement());
                    String jsonStr = redis.hget("User_" + userId, "BasicInfo");

                    if(null == jsonStr) continue;

                    RankItem rankItem = new RankItem();
                    rankItem.rankId = ++i;
                    rankItem.userId = userId;
                    rankItem.win = (int)t.getScore();

                    JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                    rankItem.userName = jsonObject.getString("userName");
                    rankItem.heroAvatar = jsonObject.getString("heroAvatar");

                    rankItemList.add((rankItem));
                }
                _rankItemList = rankItemList;

            }catch (Exception e){
                LOGGER.error(e.getMessage(), e);
            }
        }
    }
}
